package org.xingole.jgit.lib;

/**
 * A reference that indirectly points at another Ref.
 *
 * <p>A symbolic reference always derives its current value from the target reference.</p>
 */
public class SymbolicRef implements Ref {
    // Please remember the symbolic storage way is always LOOSE format.
    private final String name;

    private final Ref target;

    /**
     * Create a new ref pairing.
     * @param refName - name of this ref.
     * @param target - the ref we reference and derive our value from.
     */
    public SymbolicRef(String refName, Ref target) {
        this.name = refName;
        this.target = target;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public boolean isSymbolic() {
        return true;
    }

    @Override
    public ObjectId getObjectId() {
        return getLeaf().getObjectId();
    }

    @Override
    public Ref getLeaf() {
        Ref dst = getTarget();
        while(dst.isSymbolic())
            dst = dst.getTarget();
        return dst;
    }

    @Override
    public Ref getTarget() {
        return target;
    }

    // the leaf reference of the current symbolic reference decides the peeled state.
    @Override
    public ObjectId getPeeledObjectId() {
        return getLeaf().getPeeledObjectId();
    }

    @Override
    public boolean isPeeled() {
        return getLeaf().isPeeled();
    }

    @Override
    public Storage getStorage() { // the property is important.
        return Storage.LOOSE;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("SymbolicRef[");
        Ref cur = this;
        while (cur.isSymbolic()) {
            builder.append(cur.getName());
            builder.append(" -> ");
            cur = cur.getTarget();
        }
        builder.append(cur.getName());
        builder.append('=');
        builder.append(ObjectId.toString(cur.getObjectId()));
        builder.append("]");
        return builder.toString();
    }
}
